{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Necessary conditions for Jobsequencing\n",
    "### Install pyQUBO from Recruit Communications Co. Ltd.\n",
    "    pip install pyqubo\n",
    "### Install openJij from Jij Inc.  (startup from Tohoku University)\n",
    "    pip install openjij"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Solve Jobsequencing"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### import pyQUBO, openJij, numpy, and matplotlib"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pyqubo  import Array,Constraint, Placeholder\n",
    "import openjij as jij\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Array, Constrains and Placeholders are convenient classes from pyQUBO"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Prepare binary variables"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "N = 10\n",
    "M = 3\n",
    "ymax = 10\n",
    "vartype = \"BINARY\"\n",
    "q = Array.create(\"q\",shape=[M,N],vartype=vartype)\n",
    "y = Array.create(\"y\",shape=ymax,vartype=vartype)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\"q\" is name of variables  \n",
    "shape specifies the shape of variables as vector, matrix, or...  \n",
    "vartype selects -1 or 1 by \"SPIN\" and 0 or 1by \"BINARY\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Array([[Binary(q[0][0]), Binary(q[0][1]), Binary(q[0][2]), Binary(q[0][3]), Binary(q[0][4]), Binary(q[0][5]), Binary(q[0][6]), Binary(q[0][7]), Binary(q[0][8]), Binary(q[0][9])],\n",
      "       [Binary(q[1][0]), Binary(q[1][1]), Binary(q[1][2]), Binary(q[1][3]), Binary(q[1][4]), Binary(q[1][5]), Binary(q[1][6]), Binary(q[1][7]), Binary(q[1][8]), Binary(q[1][9])],\n",
      "       [Binary(q[2][0]), Binary(q[2][1]), Binary(q[2][2]), Binary(q[2][3]), Binary(q[2][4]), Binary(q[2][5]), Binary(q[2][6]), Binary(q[2][7]), Binary(q[2][8]), Binary(q[2][9])]])\n"
     ]
    }
   ],
   "source": [
    "print(q)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Array([Binary(y[0]), Binary(y[1]), Binary(y[2]), Binary(y[3]), Binary(y[4]), Binary(y[5]), Binary(y[6]), Binary(y[7]), Binary(y[8]), Binary(y[9])])\n"
     ]
    }
   ],
   "source": [
    "print(y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Prepare values and weights"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "Lmax = 5\n",
    "L = np.random.randint(1,Lmax,N)\n",
    "n = np.linspace(1,ymax,ymax)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Define cost function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "E1 = Constraint(np.sum((np.sum(q,axis=0)-1)**2,axis=0),\"select\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "E2 = 0\n",
    "for k in range(M):\n",
    "    temp = 0\n",
    "    for i in range(N):\n",
    "        temp += L[i]*(q[k][i]-q[0][i])\n",
    "    temp += np.dot(n,y)\n",
    "    E2 += temp**2\n",
    "E2 = Constraint(E2,\"y\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "E3 = 0\n",
    "for i in range(N):\n",
    "    E3 += L[i]*q[0][i]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "Lam1 = Placeholder('Lam1')\n",
    "Lam2 = Placeholder('Lam2')\n",
    "E_cost = Lam1*E1+Lam2*E2+E3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Compile the cost function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = E_cost.compile()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Get qubo matrix"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "feed_dict = {'Lam1': 10.0,'Lam2': 10.0}\n",
    "Q, offset = model.to_qubo(feed_dict=feed_dict)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Prepare simulation of quantum annealing"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "#simulated quantum annealing\n",
    "sampler = jij.SQASampler(beta=10.0, gamma=1.0, trotter=4, num_sweeps=100)\n",
    "#simulated annealing\n",
    "#sampler = jij.SASampler(num_sweeps=1000)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This is done by quantum Monte-Carlo simulation  \n",
    "gamma = strength of quantum fluctuation  \n",
    "trotter = Trotter number  \n",
    "num_sweeps = length of MCS"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Let's simulate quantum annealing"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "response = sampler.sample_qubo(Q)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Show results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  q[0][0] q[0][1] q[0][2] q[0][3] q[0][4] q[0][5] ... y[9] energy num_oc.\n",
      "0       1       0       1       0       0       0 ...    0   65.0       1\n",
      "['BINARY', 1 rows, 1 samples, 40 variables]\n"
     ]
    }
   ],
   "source": [
    "print(response)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### minimum sample"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1,\n",
       "        1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=int8)"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "response.record[\"sample\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### decode solution through pyQUBO"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "dsol, broken, energy = model.decode_solution(response.record[\"sample\"][0], feed_dict = feed_dict, vartype=vartype)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{0: {0: 1, 1: 0, 2: 1, 3: 0, 4: 0, 5: 0, 6: 1, 7: 1, 8: 0, 9: 1},\n",
       " 1: {0: 0, 1: 1, 2: 0, 3: 0, 4: 1, 5: 0, 6: 1, 7: 1, 8: 0, 9: 0},\n",
       " 2: {0: 0, 1: 1, 2: 1, 3: 0, 4: 1, 5: 1, 6: 1, 7: 0, 8: 0, 9: 0}}"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dsol[\"q\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0}"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dsol[\"y\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Show results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "time = np.zeros(M)\n",
    "for k in range(M):\n",
    "    for keys in dsol[\"q\"][k]:\n",
    "        if dsol[\"q\"][k][keys] == 1:\n",
    "            time[k] += L[keys]\n",
    "plt.bar(range(M),time)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
